package com.mew.chess.core.game.pokdeng.game.core;

import com.mew.chess.core.game.pokdeng.game.common.PokDengCardType;
import com.mew.chess.core.game.pokdeng.game.message.UserMessage;
import com.mew.common.entity.user.User;
import com.mew.common.util.TxtUtils;

import java.util.*;

/**
 * @author dylin
 * @create 2021/5/6
 */
public class CardUtil {
    public static String DEVICE_CONFIG_PATH = "external/CardDevice/PokDeng.txt";

    private static final int MAX_CARD=52;

    private static final int MAJOR_9_VAL=900;
    private static final int MAJOR_8_VAL=800;
    private static final int THREE_OF_A_KIND_VAL=400;
    private static final int STRAIGHT_FLUSH_VAL=300;
    private static final int STRAIGHT_VAL=200;
    private static final int SAN_KUNG_VAL=100;

    private static final List<Integer> cardLib=new ArrayList<>();
    private static Map<Integer,List<Integer>> controlCard=new HashMap<>();

    /**
     * 洗牌
     * @return
     */
    public static List<Integer> getShuffleCardLib(){
        if(cardLib.size()==0){
            //把所有牌添加进牌库
           for(int c=0;c<MAX_CARD;c++){
               cardLib.add(c);
           }
        }
        Collections.shuffle(cardLib);
        return cardLib;
    }

    /**
     * 发一张牌
     */
    public static int deal(List<Integer> cardLib,int seat,boolean control,int cardSize){
        int card=-1;
        if(control){
            card=deal(seat,cardSize);
        }
        if(card==-1){
            card=cardLib.get(0);
            cardLib.remove(0);
        }
        return card;
    }

    /**
     * 控制  发一张牌
     * @param seat
     * @param cardSize
     * @return
     */
    private static int deal(int seat,int cardSize){
        List<Integer> cards=controlCard.get(seat);
        if(null!=cards&&cards.size()>cardSize){
            return cards.get(cardSize);
        }else{
            return -1;
        }
    }
    /**
     * 是否需要补牌
     * @param cards
     * @return
     */
    public static boolean isNeedSysDeal(List<Integer> cards){
        if(cards.size()!=2){
            return false;
        }
        return computeCardsVal(cards)<4;
    }
    /**
     * 计算牌的面值
     * @return
     */
    public static int computeCardVal(Integer card){
        int val=card%13+1;
        if(val>10){
            val=0;
        }
        return val;
    }
    /**
     * 计算牌的面值 不特殊处理JQKA
     * @return
     */
    public static int computeCardValJQKA(Integer card){
        int val=card%13+1;
        if(val==1){
           val=14;
        }
        return val;
    }

    /**
     * 计算手牌大小
     * @param cards 牌
     * @return
     */
    public static int computeCardsVal(List<Integer> cards){
        int val=0;
        for (Integer card : cards) {
            val+= computeCardVal(card);
        }
        if(val>9){
            val=val%10;
        }
        return val;
    }

    /**
     * 是否是天牌
     * @param cards
     * @return
     */
    public static int isMajor(List<Integer> cards){
        if(cards.size()!=2){
            return 0;
        }
        int val=computeCardsVal(cards);
        if(val==9){
            return MAJOR_9_VAL;
        }
        if(val==8){
            return MAJOR_8_VAL;
        }
        return 0;
    }
    /**
     * 是否是三条
     * @param cards
     * @return
     */
    public static int isThreeOfAKind(List<Integer> cards){
        if(cards.size()!=3){
            return 0;
        }
        if(computeCardValJQKA(cards.get(0))==computeCardValJQKA(cards.get(1))&&computeCardValJQKA(cards.get(1))==computeCardValJQKA((cards.get(2)))){
            return THREE_OF_A_KIND_VAL+computeCardValJQKA(cards.get(0));
        };
        return 0;
    }
    /**
     * 是否是同花顺
     * @param cards
     * @return
     */
    public static int isStraightFlush(List<Integer> cards){
        if(cards.size()!=3){
            return 0;
        }
        //不为同一花色
        if(cards.get(0)/13!=cards.get(1)/13||
                cards.get(1)/13!=cards.get(2)/13||
                cards.get(2)/13!=cards.get(0)/13
        ){
            return 0;
        }
        int s=isStraight(cards);
        if(s>0){
            return s-STRAIGHT_VAL+STRAIGHT_FLUSH_VAL;
        }
        return 0;
    }
    /**
     * 是否是顺子
     * @param cards
     * @return
     */
    public static int isStraight(List<Integer> cards){
        if(cards.size()!=3){
            return 0;
        }
        List<Integer> tc=new ArrayList<>();
        for (Integer card : cards) {
            tc.add(CardUtil.computeCardValJQKA(card));
        }
        tc.sort(Integer::compareTo);
        if(tc.get(0)+1==tc.get(1)&&tc.get(1)+1==tc.get(2)){
            return STRAIGHT_VAL+tc.stream().mapToInt(Integer::intValue).sum();
        }
        return 0;
    }
    /**
     * 是否是三公
     * @param cards
     * @return
     */
    public static int isSanKung(List<Integer> cards){
        if(cards.size()!=3){
            return 0;
        }
        int c1=CardUtil.computeCardValJQKA(cards.get(0));
        int c2=CardUtil.computeCardValJQKA(cards.get(1));
        int c3=CardUtil.computeCardValJQKA(cards.get(2));
        if(c1>10&&c1<14
         &&c2>10&&c2<14
         &&c3>10&&c3<14){
            return SAN_KUNG_VAL;
        }
        return 0;
    }

    /**
     * 是否是对子
     */
    public static boolean isPair(List<Integer> cards){
        if(cards.size()!=2){
            return false;
        }
        if(cards.get(0)%13==cards.get(1)%13){
            return true;
        }
        return false;
    }
    /**
     * 是否是同花
     */
    public static boolean isFlush(List<Integer> cards){
        if(cards.size()!=2){
            return false;
        }
        if(cards.get(0)/13==cards.get(1)/13){
            return true;
        }
        return false;
    }

    /**
     * 牌计算
     * @param user
     */
    public static void computeCard(UserMessage user){
        //初始化倍数 避免普通倍数天牌和普牌，遗传上次算牌的倍数
        user.setCardRate(1);
        List<Integer> cards=user.getCards();
        if(isPair(cards)){
            user.setCardRate(2);
        }
        if(isFlush(cards)){
            user.setCardRate(2);
        }
        int cardsVal=isMajor(cards);
        if(cardsVal>0){
            user.setCardType(PokDengCardType.Major.code());
            user.setCardVal(cardsVal);
            return;
        }
        cardsVal=isThreeOfAKind(cards);
        if(cardsVal>0){
            user.setCardType(PokDengCardType.ThreeOfAKind.code());
            user.setCardVal(cardsVal);
            user.setCardRate(5);
            return;
        }
        cardsVal=isStraightFlush(cards);
        if(cardsVal>0){
            user.setCardType(PokDengCardType.StraightFlush.code());
            user.setCardVal(cardsVal);
            user.setCardRate(5);
            return;
        }
        cardsVal=isStraight(cards);
        if(cardsVal>0){
            user.setCardType(PokDengCardType.Straight.code());
            user.setCardVal(cardsVal);
            user.setCardRate(3);
            return;
        }
        cardsVal=isSanKung(cards);
        if(cardsVal>0){
            user.setCardType(PokDengCardType.SanKung.code());
            user.setCardVal(cardsVal);
            user.setCardRate(3);
            return;
        }
        user.setCardType(PokDengCardType.None.code());
        user.setCardVal(computeCardsVal(cards));
    }
    public static boolean redCardDeviceConfig(){
        controlCard.clear();
        String read=TxtUtils.byFile(DEVICE_CONFIG_PATH);
        if(null==read||read.isEmpty()){
            return false;
        }
        try {
            String[] confs=read.split("\r\n");
            for (String conf : confs) {
                String[] onConf=conf.split(":");
                List<Integer> ins=new ArrayList<>();
                for (String s : onConf[1].split(",")) {
                    ins.add(Integer.parseInt(s));
                }
                controlCard.put(Integer.parseInt(onConf[0]),ins);
            }
            return true;
        }catch (Exception e){
            controlCard.clear();
            e.printStackTrace();
            return false;
        }
    }
}
